package com.yzmoney.common.property;

import com.yzmoney.common.message.SystemTipMessage;
import com.yzmoney.common.util.JDKStackTrace;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.text.MessageFormat;
import java.util.*;

/**
 * Properties资源读取
 * */
public class PropertyReader implements SystemTipMessage{
	
	private static Log log = LogFactory.getLog(PropertyReader.class);
	
	private static Map<String,PropertyReader> map = new HashMap<String, PropertyReader>();
	
	/**资源路径*/
	private String path;
	private ResourceBundle bundle;
	
	/**配置key列表*/
	private List<String> keyList;
	/**配置消息Map*/
	private Map<String,MessageFormat> msgMap;
	
	/**是否成功加载*/
	private boolean success = false;
	
	/**得到配置*/
	public static PropertyReader getInstance(String cfgName) {
		
		if (!map.containsKey(cfgName)){
			map.put(cfgName, new PropertyReader(cfgName));
		}
		
		return map.get(cfgName);
	}
	
	
	/**
	 * 根据路径参数创建
	 * */
	protected PropertyReader(String url) {
		this(url,Locale.getDefault());
	}
	/**
	 * 根据路径参数创建
	 * */
	protected PropertyReader(String url, Locale loc) {
		try{
			bundle = ResourceBundle.getBundle(url,loc);
			this.path = url;
			this.keyList = new ArrayList<String>();
			this.msgMap = new HashMap<String, MessageFormat>();
		}catch (RuntimeException e){
			//e.printStackTrace();
			log.warn(JDKStackTrace.getJDKStrack(e));
		}
		init();
	}

	/**
	 * 按照默认规则找到类的配置文件
	 * ※在和类相同的路径下同名以properties后缀结尾的文件
	 * */
	/*protected PropertyReader (Class cls){
		this(cls.getName());
	}*/
	
	
	/**进行模糊匹配*/
	/*private String getFuzzyMatchKey(String key){
		
		if (containsKey(key))
			return key;
		
		List<String> matchList = getMatchKeys(key,0);
		
		if (!matchList.isEmpty())
			return matchList.get(0);
		
		return null;
		
	}*/
	
	/**得到多个匹配的key
	 * @param type 0-模糊  1-前匹配即start with 2-后匹配end with
	 * */
	private List<String> getMatchKeys(String mainKey,int type) {
		List<String> matchList = new ArrayList<String>();
		
		for (String storeKey : keyList) {
			
			if (type==0 && storeKey.contains(mainKey)) {
				matchList.add(storeKey);
			}
			//fixed bug ,必须是完整的描述key
			if (type==1 && storeKey.startsWith(mainKey+".")) {
				matchList.add(storeKey);
			}
			if (type==2 && storeKey.endsWith(mainKey)) {
				matchList.add(storeKey);
			}
		}
		
		return matchList;
	}
	
	/**得到内容*/
	private String getAccurateText(String key){
		return bundle.getString(key);
	}
	
	/**
	 * 根据key得到对应的值
	 * */
	public String getText(String key){
		
		if (!containsKey(key)){
			log.info("The key <"+key+"> was not found in the path <"+path+">.");
			return null;
		}
		
		String result = getAccurateText(key);
		/*if (result==null && isFuzzyMatch)
			result = getAccurateText(getFuzzyMatchKey(key));*/
		
		return result;
	}
	
	/**是否包含key*/
	public boolean containsKey (String key){
		return keyList.contains(key);
	}
	
	/**
	 * 得到以参数开头的所有键值对<br>
	 * 例如key.a = x以及key.b =y将会以a,x;b,y的形式返回
	 * */
	public Map<String,String> getValues(String mainKey){
		
		Map<String,String> map = new HashMap<String,String>();
		for(String key:getMatchKeys(mainKey, 1)){
			//如果键是mainKey.形式的话，放进Map中
			map.put(key.substring(mainKey.length()+1), bundle.getString(key));
		}
		return map;
	}
	
	/**得到配置文件所有key*/
	public List<String> getKeys(){
		return keyList;
	}
	
	@Override
	public String getMessage(String key, Locale locale, Object... args) {
		return null;
	}
	
	@Override
	public String getMessage(String key, Object... args) {
		
		if (!containsKey(key)){
			log.info("request key : <"+key+">was not found in Message List,please check the config file.");
			return null;
		}
		
		return msgMap.get(key).format(args);
	}
	
	/**设置模糊匹配*/
	/*public void setFuzzyMatch(boolean isFuzzyMatch) {
		this.isFuzzyMatch = isFuzzyMatch;
	}*/
	
	/**重新加载配置文件*/
	public void reload (){
		clearCache();
		_reload();
	}
	
	/**清理缓存*/
	private static void clearCache(){
		ResourceBundle.clearCache(PropertyReader.class.getClassLoader());
	}
	
	/**重新加载*/
	private void _reload(){
		if (success){
			bundle = ResourceBundle.getBundle(path, bundle.getLocale());
		}
		keyList.clear();
		msgMap.clear();
		init();
		log.info("Properties file <"+path+"> has been reloaded");
	}
	
	/**重新加载所有配置文件*/
	public static void reloadAll (){
		clearCache();
		for (PropertyReader pr : map.values()){
			pr._reload();
		}
		log.info("All properties has been reloaded.");
	}
	
	/**初始化*/
	private void init(){
		
		String temp;
		
		if (bundle==null)
			return;
		
		for(String key:bundle.keySet()){
			temp = bundle.getString(key);
			if (temp.contains("{") && temp.contains("}"))
				msgMap.put(key, new MessageFormat(temp));
			keyList.add(key);
		}
		
		success = true;
	}
}
